<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>晶体结构测试</title>
    <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/jsm/controls/OrbitControls.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background: #0a0a0a;
        }

        canvas {
            display: block;
        }

        .controls {
            position: absolute;
            top: 10px;
            left: 10px;
            background: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 15px;
            border-radius: 8px;
            font-family: Arial, sans-serif;
        }

        button {
            background: #007bff;
            color: white;
            border: none;
            padding: 8px 16px;
            margin: 5px;
            border-radius: 4px;
            cursor: pointer;
        }

        button:hover {
            background: #0056b3;
        }
    </style>
</head>

<body>
    <div class="controls">
        <h3>晶体结构测试</h3>
        <button onclick="toggleCrystalMode()">切换晶体模式</button>
        <button onclick="changeUnitCells(1)">1x1x1</button>
        <button onclick="changeUnitCells(2)">2x2x2</button>
        <button onclick="changeUnitCells(3)">3x3x3</button>
        <div id="status">当前模式: 单个分子</div>
    </div>

    <script>
        let scene, camera, renderer, controls;
        let crystalMode = false;
        let unitCells = 1;

        function init() {
            // 创建场景
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0x0a0a0a);

            // 创建相机
            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.z = 15;

            // 创建渲染器
            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);

            // 添加轨道控制
            controls = new THREE.OrbitControls(camera, renderer.domElement);
            controls.enableDamping = true;

            // 添加灯光
            const ambientLight = new THREE.AmbientLight(0x404040, 0.6);
            scene.add(ambientLight);

            const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
            directionalLight.position.set(1, 1, 1);
            scene.add(directionalLight);

            // 创建测试晶体结构（硅晶体）
            createSiliconCrystal();

            animate();
        }

        function createSiliconCrystal() {
            // 清除现有场景
            while (scene.children.length > 0) {
                scene.remove(scene.children[0]);
            }

            // 重新添加灯光
            const ambientLight = new THREE.AmbientLight(0x404040, 0.6);
            scene.add(ambientLight);

            const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
            directionalLight.position.set(1, 1, 1);
            scene.add(directionalLight);

            // 硅晶体的晶格参数（金刚石结构）
            const lattice = {
                a: 5.43, b: 5.43, c: 5.43,
                alpha: 90, beta: 90, gamma: 90
            };

            // 硅原子的分数坐标（金刚石结构）
            const atoms = [
                { species: ['Si'], xyz: [0, 0, 0], label: 'Si' },
                { species: ['Si'], xyz: [0.5, 0.5, 0], label: 'Si' },
                { species: ['Si'], xyz: [0.5, 0, 0.5], label: 'Si' },
                { species: ['Si'], xyz: [0, 0.5, 0.5], label: 'Si' },
                { species: ['Si'], xyz: [0.25, 0.25, 0.25], label: 'Si' },
                { species: ['Si'], xyz: [0.75, 0.75, 0.25], label: 'Si' },
                { species: ['Si'], xyz: [0.75, 0.25, 0.75], label: 'Si' },
                { species: ['Si'], xyz: [0.25, 0.75, 0.75], label: 'Si' }
            ];

            if (crystalMode) {
                // 晶体模式：显示多个晶胞
                renderCrystalStructure(atoms, lattice);
            } else {
                // 单个分子模式
                renderSingleUnitCell(atoms, lattice);
            }
        }

        function renderSingleUnitCell(atoms, lattice) {
            // 渲染晶胞边界框
            renderUnitCellBoundary(lattice);

            // 渲染单个晶胞内的原子
            atoms.forEach(atom => {
                const sphere = createAtom(atom, lattice, 0, 0, 0);
                scene.add(sphere);
            });

            document.getElementById('status').textContent = '当前模式: 单个晶胞';
        }

        function renderCrystalStructure(atoms, lattice) {
            // 渲染晶胞边界框
            renderUnitCellBoundary(lattice);

            const range = Math.floor(unitCells / 2);

            // 扩展到多个晶胞
            for (let i = -range; i <= range; i++) {
                for (let j = -range; j <= range; j++) {
                    for (let k = -range; k <= range; k++) {
                        atoms.forEach(atom => {
                            const sphere = createAtom(atom, lattice, i, j, k);
                            scene.add(sphere);
                        });
                    }
                }
            }

            document.getElementById('status').textContent = `当前模式: 晶体结构 (${unitCells}x${unitCells}x${unitCells})`;
        }

        function createAtom(atom, lattice, i, j, k) {
            const elementSymbol = atom.species[0];
            const color = getAtomColor(elementSymbol);
            const radius = 0.4; // 原子半径

            const geometry = new THREE.SphereGeometry(radius, 16, 16);
            const material = new THREE.MeshPhongMaterial({ color });
            const sphere = new THREE.Mesh(geometry, material);

            // 将分数坐标转换为笛卡尔坐标
            const x = (atom.xyz[0] + i - 0.5) * lattice.a;
            const y = (atom.xyz[1] + j - 0.5) * lattice.b;
            const z = (atom.xyz[2] + k - 0.5) * lattice.c;

            sphere.position.set(x, y, z);
            return sphere;
        }

        function renderUnitCellBoundary(lattice) {
            const a = lattice.a;
            const b = lattice.b;
            const c = lattice.c;

            // 创建晶胞边界框的几何体
            const edges = [
                // 底面
                [0, 0, 0], [a, 0, 0],
                [0, 0, 0], [0, b, 0],
                [a, 0, 0], [a, b, 0],
                [0, b, 0], [a, b, 0],

                // 顶面
                [0, 0, c], [a, 0, c],
                [0, 0, c], [0, b, c],
                [a, 0, c], [a, b, c],
                [0, b, c], [a, b, c],

                // 侧面
                [0, 0, 0], [0, 0, c],
                [a, 0, 0], [a, 0, c],
                [0, b, 0], [0, b, c],
                [a, b, 0], [a, b, c]
            ];

            const points = [];
            edges.forEach(edge => {
                points.push(new THREE.Vector3(edge[0] - a / 2, edge[1] - b / 2, edge[2] - c / 2));
            });

            const geometry = new THREE.BufferGeometry().setFromPoints(points);
            const material = new THREE.LineBasicMaterial({
                color: 0x00ffff,
                transparent: true,
                opacity: 0.6,
                linewidth: 2
            });

            const line = new THREE.LineSegments(geometry, material);
            scene.add(line);
        }

        function getAtomColor(element) {
            const colors = {
                'H': 0xFFFFFF, 'C': 0x909090, 'N': 0x3050F8,
                'O': 0xFF0D0D, 'F': 0x90E050, 'Cl': 0x1FF01F,
                'Br': 0xA62929, 'I': 0x940094, 'Si': 0xF0C8A0,
                'default': 0xFF69B4
            };
            return colors[element] || colors['default'];
        }

        function toggleCrystalMode() {
            crystalMode = !crystalMode;
            createSiliconCrystal();
        }

        function changeUnitCells(cells) {
            unitCells = cells;
            if (crystalMode) {
                createSiliconCrystal();
            }
        }

        function animate() {
            requestAnimationFrame(animate);
            controls.update();
            renderer.render(scene, camera);
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        window.addEventListener('resize', onWindowResize, false);
        init();
    </script>
</body>

</html>